package service

import (
	"goframe-zc/dto"
	"goframe-zc/internal/dao"
	"goframe-zc/utility"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

// 单例模式（全局唯一实例）
var User = userService{}

type userService struct{}

// 注册业务：检查手机号是否已存在 -> 加密密码 -> 插入数据库
func (s *userService) Register(ctx g.Ctx, phone, pass string) (int, error) {
	// 1. 检查手机号是否已注册
	count, err := dao.ZcUser.Ctx(ctx).Where("phone", phone).Count()
	if err != nil {
		return 0, err
	}
	if count > 0 {
		return 0, gerror.New("手机号已存在!")
	}

	// 2. 密码加密
	encryptPass := utility.PasswordEncrypt(pass)
	// 3. 插入数据库
	result, err := dao.ZcUser.Ctx(ctx).Insert(g.Map{
		"phone": phone,
		"pass":  encryptPass,
	})
	if err != nil {
		return 0, gerror.New("注册失败：" + err.Error())
	}

	// 4. 返回新用户ID
	userID, _ := result.LastInsertId()
	return gconv.Int(userID), nil
}

// 登录业务：检查用户是否存在 -> 验证密码 -> 生成JWT令牌
func (s *userService) Login(ctx g.Ctx, phone, pass string) (interface{}, error) {
	// 1. 查询用户信息
	userInfo, err := dao.ZcUser.Ctx(ctx).Where("phone", phone).One()
	if err != nil {
		return "", gerror.New("查询用户失败：" + err.Error())
	}
	if userInfo.IsEmpty() {
		return "", gerror.New("手机号不存在")
	}
	// 2. 验证密码（明文与加密密码比对）
	if utility.PasswordEncrypt(pass) != userInfo["password"].String() {
		return "", gerror.New("手机号或密码错误")
	}
	//
	// 3. 生成JWT令牌
	uid := userInfo["id"].Int()
	//if err1 != nil {
	//	return "", gerror.New("类型转换失败：" + err1.Error())
	//}
	token, err := utility.JWT.Generate(uid)
	if err != nil {
		return "", gerror.New("生成令牌失败：" + err.Error())
	}
	dataMap := userInfo.Map()
	dataMap["token"] = token
	// 2. 转换为目标结构体（自动映射字段：record中的"phone" -> 结构体的Mobile）
	var userLoginJSON dto.UserLoginJSON
	if err := gconv.Struct(dataMap, &userLoginJSON); err != nil {
		return nil, err
	}
	//if err := gconv.Struct(token, &userLoginJSON); err != nil {
	//	return nil, err
	//}
	//
	return userLoginJSON, nil
}

// 获取用户信息：根据用户ID查询数据库（屏蔽敏感字段）
func (s *userService) GetInfo(ctx g.Ctx, userID int) (dto.UserInfoJSON, error) {
	var userInfoJSON dto.UserInfoJSON
	userInfo, err := dao.ZcUser.Ctx(ctx).Where("id", userID).One()
	if err != nil {
		return userInfoJSON, gerror.New("查询用户信息失败：" + err.Error())
	}
	if userInfo.IsEmpty() {
		return userInfoJSON, gerror.New("用户不存在")
	}
	user := userInfo.Map()

	// 2. 转换为目标结构体（自动映射字段：record中的"phone" -> 结构体的Mobile）
	if err := gconv.Struct(user, &userInfoJSON); err != nil {
		return userInfoJSON, err
	}
	//if err := gconv.Struct(token, &userLoginJSON); err != nil {
	//	return nil, err
	//}
	//
	return userInfoJSON, nil
}

// 获取用户订单列表信息：根据用户ID查询数据库（屏蔽敏感字段）
func (s *userService) GetOrderList(ctx g.Ctx, userID int) (dto.UserInfoJSON, error) {
	var userInfoJSON dto.UserInfoJSON
	userInfo, err := dao.ZcUser.Ctx(ctx).Where("id", userID).One()
	if err != nil {
		return userInfoJSON, gerror.New("查询用户信息失败：" + err.Error())
	}
	if userInfo.IsEmpty() {
		return userInfoJSON, gerror.New("用户不存在")
	}
	user := userInfo.Map()

	// 2. 转换为目标结构体（自动映射字段：record中的"phone" -> 结构体的Mobile）
	if err := gconv.Struct(user, &userInfoJSON); err != nil {
		return userInfoJSON, err
	}
	//if err := gconv.Struct(token, &userLoginJSON); err != nil {
	//	return nil, err
	//}
	//
	return userInfoJSON, nil
}
